package com.wcj.study.multidatasource.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import com.wcj.study.multidatasource.config.MultiDataSourceProperties.DsGroupProperties;

/**
 * TODO 添加类描述
 * 
 * @author 汪长军 Email：changjunwang@xinhe99.com
 * @date 2019-01-02 下午2:08:57
 * @copyright 信和上融网络科技(北京)有限公司
 */
@Order(-99)
@Configuration
@Component
@Primary
public class MultiRoutingDataSource extends AbstractRoutingDataSource implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Autowired
    private MultiDataSourceProperties multiDataSourceProperties;

    /**
     * 数据源key
     */
    private List<String> dsGroupList = new ArrayList<>();

    public MultiRoutingDataSource() {
        // DataSourceBuilder.create().type(dataSourceType).build();
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        super.setTargetDataSources(targetDataSources);
    }

    @Override
    public void afterPropertiesSet() {

        dsGroupList.clear();

        if (multiDataSourceProperties.getInstance().isEmpty()) {
            throw new RuntimeException("请配置数据源!");
        }

        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();

        for (Entry<String, DsGroupProperties> obj : multiDataSourceProperties.getInstance().entrySet()) {

            dsGroupList.add(obj.getKey());

            // 写数据源
            for (String dsName : obj.getValue().getWrite().getDsBeanNames()) {
                targetDataSources.put(dsName, applicationContext.getBean(dsName));
            }

            // 读数据源
            for (String dsName : obj.getValue().getRead().getDsBeanNames()) {
                targetDataSources.put(dsName, applicationContext.getBean(dsName));
            }
            
        }

        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    /**
     * TODO 添加方法说明
     *
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {

        String key = MultiDataSourceContext.get();

        //取默认配置的数据源组写操作
        if (StringUtils.isBlank(key)) {
            String dsGroup = multiDataSourceProperties.getDefaultDsGroup();
            DsGroupProperties dsGroupProperties = multiDataSourceProperties.getInstance().get(dsGroup);
            List<String> dsList = dsGroupProperties.getWrite().getDsBeanNames();
            key = dsList.get(RandomUtils.nextInt(0, dsList.size()));
        }
        
        return key;
    }

    /**
     * TODO 添加方法说明
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
